package main

import (
	"context"
	"fmt"
	"log/slog"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
	server := &http.Server{Addr: Config.ListeningAddr, Handler: nil}

	http.HandleFunc(Config.MetricsURLPath, func(w http.ResponseWriter, r *http.Request) {
		// 重置所有瞬时值指标
		for _, coll := range allRegisteredGaugeCollectors {
			coll.Reset()
		}

		// 开始采集数据
		ctx, cancel := context.WithTimeout(r.Context(), time.Duration(float64(time.Second)*Config.ScrapeTimeoutSec))
		defer cancel()
		scrapeAllDevices(ctx, Config.Devices)

		// 采集完成后，才返回指标数据
		promhttp.Handler().ServeHTTP(w, r)
	})

	// 启动HTTP服务器
	go func() {
		slog.Info("Starting server.", "listen_address", Config.ListeningAddr)
		slog.Info(fmt.Sprintf("Visit %s to see Prometheus metrics", Config.MetricsURLPath))

		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			slog.Error("Server failed to start", "err", err)
		}
	}()

	// 等待中断信号
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	slog.Info("Shutting down server...")

	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(float64(time.Second)*Config.ScrapeTimeoutSec))
	defer cancel()
	if err := server.Shutdown(ctx); err != nil {
		slog.Error("Server forced to shutdown.", "err", err.Error())
	}
	slog.Info("Server exited gracefully")
}
